package main

import "fmt"

type GraphAdjacencyMatrix struct {
	Vertices        []int
	AdjacencyMatrix [][]int
}

func NewGraphAdjacencyMatrix(vertices []int, edges [][]int) *GraphAdjacencyMatrix {
	g := &GraphAdjacencyMatrix{}
	g.Vertices = vertices
	g.AdjacencyMatrix = make([][]int, len(vertices))
	for i := range g.AdjacencyMatrix {
		g.AdjacencyMatrix[i] = make([]int, len(vertices))
	}

	for i := range edges {
		g.AddEdge(edges[i][0], edges[i][1])
	}

	return g
}

func (g *GraphAdjacencyMatrix) Size() int {
	return len(g.Vertices)
}

func (g *GraphAdjacencyMatrix) AddVertex(val int) {
	// 添加vertex 就是在矩阵的添加一行一列

	// 首先在订单列表中添加一个定点
	g.Vertices = append(g.Vertices, val)

	newRow := make([]int, 0, g.Size()+1)
	g.AdjacencyMatrix = append(g.AdjacencyMatrix, newRow)
	for i := range g.AdjacencyMatrix {
		g.AdjacencyMatrix[i] = append(g.AdjacencyMatrix[i], 0)
	}
}

func (g *GraphAdjacencyMatrix) RemoveVertex(index int) {
	if index < 0 || index >= g.Size() {
		return
	}

	g.Vertices = append(g.Vertices[:index], g.Vertices[index+1:]...)
	g.AdjacencyMatrix = append(g.AdjacencyMatrix[:index], g.AdjacencyMatrix[index+1:]...)
	for i := range g.AdjacencyMatrix {
		g.AdjacencyMatrix[i] = append(g.AdjacencyMatrix[i][:index], g.AdjacencyMatrix[i][index+1:]...)
	}
}

func (g *GraphAdjacencyMatrix) AddEdge(a int, b int) {
	if a < 0 || b < 0 || a >= g.Size() || b >= g.Size() || a == b {
		fmt.Println("index out of bounds exception")
		return
	}

	g.AdjacencyMatrix[a][b] = 1
	g.AdjacencyMatrix[b][a] = 1
}

func (g *GraphAdjacencyMatrix) RemoveEdge(a, b int) {
	if a < 0 || b < 0 || a >= g.Size() || b >= g.Size() || a == b {
		fmt.Println("index out of bounds exception")
		return
	}
	g.AdjacencyMatrix[a][b] = 0
	g.AdjacencyMatrix[b][a] = 0
}

func (g *GraphAdjacencyMatrix) Print() {
	fmt.Printf("vertex: \t\t%v\n", g.Vertices)
	fmt.Println("adjacency matrix:")
	for i := range g.AdjacencyMatrix {
		fmt.Printf("\t\t\t%v\n", g.AdjacencyMatrix[i])
	}
}
